<template>
  <div class="excel-preivew-wp" ref="excelPreviewRef">
  	<div class="excel-scroll">
  		<div class="pdf-box" :style="{'--pdf-width': _d.pdfWidth+'px'}">
	  		<div ref="pdfBoxRef"></div>
	  	</div>
  	</div>

  	<div v-if="_d.handleList.length" class="tbody-handle">
  		<div class="show-text">列表<br/>操作</div>
  		<div class="handle-box">
  			<div v-for="(item, index) in _d.handleList" :key="index" class="row">
  				<div class="name">{{item.name}}：</div>
		  		<el-button v-if="_d.config.copyTbody" class="copy" @click="copyTbody(item)">粘贴</el-button>
	  			<el-button class="add" @click="addRow(item)">添加</el-button>
	  			<el-input class="ipt" v-model="item.num" placeholder="删除行"/>
	  			<el-button class="delete" @click="deleteRow(item)">删除</el-button>
  			</div>
  		</div>
  	</div>

  	<table class="gd-table" ref="gdTableRef">
  		<tbody></tbody>
  	</table>

  	<div class="gd-tools">
  		<div v-for="(item, index) in _d.gdTools" :key="item.id">
  			<div :id="item.id" class="operate_tool" :style="item.style">
  				<template v-if="item.type == 'input'">
	  				<el-input style="width:100%;" v-model="item.value" placeholder="请输入" @change="inputChange(item)"/>
	  			</template>
	  			<template v-if="item.type == 'inputNumber'">
	  				<el-input-number style="width:100%;" v-model="item.value" placeholder="请输入" @change="inputChange(item)"/>
	  			</template>
	  			<template v-if="item.type == 'textarea'">
	  				<el-input style="width:100%;" v-model="item.value" type="textarea" :rows="item.rows" placeholder="请输入" @change="inputChange(item)"/>
	  			</template>
	  			<template v-if="item.type == 'date'">
	  				<el-date-picker style="width:100%;" v-model="item.value" :type="item.dateType" :format="item.format" :value-format="item.format" placeholder="请选择" @change="inputChange(item)"/>
	  			</template>
	  			<template v-if="item.type == 'choiceUnit'">
	  				<choiceUnit v-model="item.value" :isInit="props.isInit" @change="inputChange(item)"/>
	  			</template>
	  			<template v-if="item.type == 'mSelect'">
	  				<mSelect v-model="item.value"
	  					:method="item.method"
	  					:url="item.url"
	  					:labelKey="item.labelKey"
	  					:valueKey="item.valueKey"
	  					:formatLabel="item.formatLabel"
	  					@change="inputChange(item)"/>
	  			</template>
	  			<template v-if="item.type == 'selectSupplier'">
	  				<selectSupplier v-model="item.value" :isInit="props.isInit" @change="inputChange(item)"/>
	  			</template>
	  			<!-- <template v-if="item.type == 'selectSupplierPerson'">
	  				<selectSupplierPerson v-model="item.value" :isInit="props.isInit" @change="inputChange(item)"/>
	  			</template> -->
	  			<template v-if="item.type == 'text'">
	  				<div>{{item.format ? formatValue(item.value, item.format) : item.value}}</div>
	  			</template>
  			</div>
  		</div>
  	</div>

  	<div ref="exportBoxRef" class="export-box"></div>


  	<div v-show="false" ref="AddDeleteRef"></div>

  	<addSupplierManage ref="addSupplierManageRef"/>
  	<addSupplierManagePerson ref="addSupplierManagePersonRef"/>
  </div>
</template>

<script setup>
	import { reactive, ref, watch, onMounted, onUnmounted } from 'vue'
	import {useRouter, useRoute} from "vue-router";
	import {getId, waitTimeout, tableToExcel, copyToClipboard, downloadPDF} from "/@/utils/Tools.js"
	import { ElMessage } from 'element-plus'
	import request from '/@/utils/request';
	import $ from "jquery";
	import html2canvas from "html2canvas";
	import choiceUnit from "./choiceUnit.vue";
	import mSelect from "./mSelect.vue";
	import selectSupplier from "./selectSupplier.vue";
	// import selectSupplierPerson from "./selectSupplierPerson.vue";
	import addSupplierManage from "/@/views/SupplierManage/modules/addModal.vue";
	import addSupplierManagePerson from "/@/views/SupplierManage/modules/addPersonModal.vue";

	const router = useRouter();
	const route = useRoute();
	const excelPreviewRef = ref();
	const pdfBoxRef = ref();
	const gdTableRef = ref();
	const exportBoxRef = ref();
	const AddDeleteRef = ref();


	const addSupplierManageRef = ref();
	const addSupplierManagePersonRef = ref();

	const props = defineProps({
		// 是否组件，组件数据使用props.config，页面数据使用接口
		isCmp: {
			type: Boolean,
			default: false
		},
		config: {
			type: Object,
			default: () => ({})
		},
		isInit: {
			type: Boolean,
			default: true
		}
	})

	// 如果是组件时，格式化数据
	watch(() => props.config, () => {
		initData();
	})

	const _d = reactive({
		pdfWidth: 0, 

		// 配置
		config: {},
		// 添加的次数
		addNum: 0,
		// 过渡工具
		gdTools: [],
		// 工具
		table: {
			head: [],
			body: [],
			footer: []
		},

		// tbody的操作行
		handleList: []
	})

	onMounted(() => {
		initData();

		window.addEventListener('resize', getPdfWidth);
	})

	onUnmounted(() => {
		window.removeEventListener('resize', getPdfWidth);
	})

	// 获取pdf宽度
	function getPdfWidth() {
		_d.pdfWidth = pdfBoxRef.value.clientWidth;
	}

	// 初始化数据
	async function initData() {
		// 设置配置内容
		let config = JSON.parse(JSON.stringify(props.config));
		config.content = config.content.replace(/\$fn_getId/g, function () {
			return 'TOOL_'+getId(5);
		})
		_d.config = config;
		if(!_d.config.content) {
			return;
		}

		// 清空
		_d.gdTools = [];
		await waitTimeout(100);

		// 格式化tBody内容
		let oData = formateTable(_d.config.content);
		// 设置table数据
		pdfBoxRef.value.innerHTML = oData.html;
		// 设置过渡操作
		_d.gdTools = [...oData.tools];
		setTimeout(() => {
			// 替换输入框
			replaceInput();
			// 计算tbody操作
			tbodyHandle();
			// 计算pdf宽度
			getPdfWidth();
			// 执行初始化
			if(props.isInit) {
				doTemplateMounted();
			}
		}, 100);
	}

	// 格式化数据
	function formateTable(data) {
		let aArr = data.split('##');
		// 获取表格html，与操作组件
		let html = '';
		let tools = [];
		aArr.forEach((str, index) => {
			if(str.indexOf('json:') == 0) {
				let obj = JSON.parse(str.substring(5));
				if(obj.type == 'inputNumber') {
					obj.value = Number(obj.value || 0);
				}
				html += `<div class="replace_box" data-id="${obj.id}"></div>`;
				tools.push(obj);
			} else {
				html += str;
			}
		})

		return {
			html,
			tools
		}
	}

	// 替换输入框
	function replaceInput() {
		let aReplaceBox = excelPreviewRef.value.querySelectorAll('.replace_box');
		for(let i = 0; i < aReplaceBox.length; i++) {
			let oBox = aReplaceBox[i];
			let oIpt = document.getElementById(oBox.dataset.id);
			oBox.parentNode.replaceChild(oIpt, oBox);
		}
		// 获取表格工具列表
		// getTableTools();
	}

	// 执行模板初始化
	function doTemplateMounted() {
		if(_d.config.onMounted) {
			let code = `window.templateOnMounted = function(route, request, ElMessage, Tools) {${_d.config.onMounted}}`;
			eval(code);
			window.templateOnMounted(route, request, ElMessage, _d.gdTools);
		}
		// if(route.path != '/ProjectManage/fillInForm') {
		// 	return;
		// }
		// let id = window.localStorage.getItem('project_id');
		// if(!id) {
		// 	return;
		// }
		// request({
		// 	url: '/api/projectService/getproject',
		// 	method: 'post',
		// 	data: id
		// }).then(res => {
		// 	if(res.data.code == 200) {
		// 		let obj = res.data.result;
		// 		_d.gdTools.forEach(item => {
		// 			if(item.label == '拟采购项目名称') {
		// 				item.value = obj.projectName;
		// 			} else if(item.label == '拟采购预算资金') {
		// 				item.value = obj.budget;
		// 			}
		// 		})
		// 	}
		// })
	}

	// 添加tbody的操作
	function tbodyHandle() {
		let list = [];
		// 根据tabody的handle-key决定是否加入添加删除按钮
		let tBody = pdfBoxRef.value.querySelectorAll('tbody');
		for(let i = 0; i < tBody.length; i++) {
			let oTBody = tBody[i];
			let key = oTBody.getAttribute('handle-key');
			if(key) {
				let obj = {
					name: oTBody.getAttribute('handle-name') || '列表', 
					key: key, 
					num: ''
				}
				list.push(obj);
			}
		}
		_d.handleList = list;
	}

	// 获取表格工具列表
	function getTableTools() {
		setTimeout(() => {
			let arr = [];
			_d.table.head = getTools(pdfBoxRef.value.querySelector('thead'));
			_d.table.body = getTools(pdfBoxRef.value.querySelector('tbody'));
			_d.table.footer = getTools(pdfBoxRef.value.querySelector('tfooter'));
		}, 50);
	}

	// 获取当前选择器下的所有工具
	function getTools(dom) {
		let arr = [];
		if(!dom) {
			return arr;
		}
		let aTr = dom.querySelectorAll('tr');
		for(let i = 0; i < aTr.length; i++) {
			let oTr = aTr[i];
			let aTools = oTr.querySelectorAll('.operate_tool');
			let brr = [];
			for(let j = 0; j < aTools.length; j++) {
				let id = aTools[j].id;
				let obj = _d.gdTools.find(item => item.id == id);
				brr.push(obj);
			}
			arr.push(brr);
		}
		return arr;
	}

	// 添加行
	async function addRow(row, addNum = 1) {
		if(!_d.config.add) {
			return;
		}
		let key = row.key;
		let oTbody = pdfBoxRef.value.querySelector(`tbody[handle-key="${key}"]`);

		let code = `window.oAdd = ${_d.config.add}`;
		eval(code);
		let addCode = window.oAdd['add_'+key];
		let addHtml = '';
		for(let i = 0; i < addNum; i++) {
			addHtml+=addCode;
		}
		// 生成id
		addHtml = addHtml.replace(/\$fn_getId/g, function () {
			return 'TOOL_'+getId(5);
		})
		// 获取添加后的code
		_d.config.content = await getAddDeleteHtml(_d.config.content, key, addHtml);
		// 转换添加
		let oData = formateTable(addHtml);
		// 设置过渡操作
		_d.gdTools.push(...oData.tools);
		// 设置节点
		let gdTbody = gdTableRef.value.querySelector('tbody');
		gdTbody.innerHTML = oData.html;
		setTimeout(() => {
			let children = gdTbody.children;
			let length = children.length;
			for(let i = 0; i < length; i++) {
				oTbody.appendChild(children[0]);
			}
			setTimeout(() => {
				// 替换输入
				replaceInput();
				// 获取表格工具列表
				getTableTools();
			}, 50);
		}, 50);
	}

	// 删除行
	async function deleteRow(row) {
		if(!_d.config.add) {
			return;
		}
		let key = row.key;
		let oTbody = pdfBoxRef.value.querySelector(`tbody[handle-key="${key}"]`);

		// 根据addCode计算需要删除几行
		let code = `window.oAdd = ${_d.config.add}`;
		eval(code);
		let addCode = window.oAdd['add_'+key];
		let lines = addCode.split('<tr').length-1;
		if(lines >= oTbody.querySelectorAll('tr').length) {
			ElMessage.error('不能更少了');
			return;
		}
		// 执行删除
		let last = oTbody.children.length-1;
		let num = row.num;
		if(num > 0 && num < last) {
			last = num - 1;
		}
		for(let i = 0; i < lines; i++) {
			let child = oTbody.children[last-i];
			oTbody.removeChild(child);
		}
		// 保存删除结果到_d.config中
		_d.config.content = await getAddDeleteHtml(_d.config.content, key, lines);
	}

	// 粘贴
	function copyTbody(row) {
		if(!_d.config.copyTbody || !_d.config.add) {
			return;
		}
		let key = row.key;
		let oTbody = pdfBoxRef.value.querySelector(`tbody[handle-key="${key}"]`);

		let tds = oTbody.firstElementChild.children.length;
		// 根据addCode计算需要每一组几行
		let code = `window.oAdd = ${_d.config.add}`;
		eval(code);
		let addCode = window.oAdd['add_'+key];
		let lines = addCode.split('<tr').length-1;

		navigator.clipboard.readText().then(async str => {
			// 格式化粘贴板内容
			let res = [];
			let arr = str.split('\r\n');
			for(let i = 0; i < arr.length; i++) {
				let brr = arr[i].split('\t');
				if(brr.length == 1 && brr[0] == '') {
					continue;
				}
				if(brr.length != tds || arr.length%lines != 0) {
					ElMessage({
						message: '粘贴内容格式错误',
						type: 'error'
					})
					return;
				} else {
					res.push(brr);
				}
			}
			// 根据需要copy的行，执行addCode
			// 当前tbody有多少行
			let rows = oTbody.children.length;
			// 从后往前判断有多少行为空
			let emptyRow = 0;
			outfor:for(let i = rows-1; i >= 0; i--) {
				let tools = oTbody.children[i].querySelectorAll('.operate_tool');
				for(let j = 0; j < tools.length; j++) {
					let id = tools[j].id;
					let oTool = _d.gdTools.find(item => item.id == id);
					if(oTool.value) {
						break outfor;
					}
				}
				emptyRow++;
			}
			// 不为空的行数
			let startRow = rows - emptyRow;
			// 计算需要添加多少个addCode
			let addNum = res.length > emptyRow ? res.length - emptyRow : 0;
			if(addNum > 0) {
				// 执行添加行
				addRow(row, addNum);
			}
			// 等待执行完成
			await waitTimeout(500);

			// 获取所有需要设置的id
			let addIds = [];
			for(let i = 0; i < res.length; i++) {
				let aIdx = startRow+i;
				let ids = [];
				let tools = oTbody.children[aIdx].querySelectorAll('.operate_tool');
				for(let j = 0; j < tools.length; j++) {
					ids.push(tools[j].id);
				}
				addIds.push(ids);
			}

			// 根据执行
			let code = `window.copyTbodyFn = function (ids, list, setValue) {${_d.config.copyTbody}}`;
			eval(code);
			window.copyTbodyFn(addIds, res, setToolValue);

			// addIds.forEach(function (aVal, aIdx) {
			// 	console.log('aIdx:'+aIdx);
			// 	console.log(aVal);
			// 	aVal.forEach(function (id, bIdx) {
			// 		console.log(bIdx);
			// 		var value = res[aIdx][bIdx];
			// 		console.log(value);
			// 		setToolValue(id, value);
			// 	})
			// })
		}).catch(err => {
			console.log(err);
		})
	}

	// 设置tool的值
	function setToolValue(id, value) {
		let obj = _d.gdTools.find(item => item.id == id);
		if(obj) {
			obj.value = value;
		}
	}


	// 获取转换后的内容，code为字符串是添加，为数字为删除
	async function getAddDeleteHtml(htmlCode, tbodyKey, code) {
		AddDeleteRef.value.innerHTML = htmlCode;
		await waitTimeout(50);
		let tBody = AddDeleteRef.value.querySelector(`tbody[handle-key="${tbodyKey}"]`);
		if(typeof code == 'string') {
			tBody.innerHTML += code;
		} else if(typeof code == 'number') {
			for(let i = 0; i < code; i++) {
				tBody.removeChild(tBody.lastElementChild);
			}
 		}
		return AddDeleteRef.value.innerHTML;
	}

	// 行改变
	function inputChange(tool) {
		if(_d.config.change) {
			let code = `window.changeFunction = function(tool, request, ElMessage, Tools) {${_d.config.change}}`;
			eval(code);
			window.changeFunction(tool, request, ElMessage, _d.gdTools);
		}
	}

	// 获取当前的content内容
	function getContentCode() {
		let html = _d.config.content;
		// 分割
		let aHtml = html.split('##');
		html = '';
		aHtml.forEach((str, index) => {
			if(str.indexOf('json:') == 0) {
				let obj = JSON.parse(str.substring(5));
				let oTool = _d.gdTools.find(item => item.id == obj.id);
				obj.value = oTool.value;
				html+=`##json:${JSON.stringify(obj)}##`;
			} else {
				html+=str;
			}
		})
		return html;
	}

	// 获取当前的contentHtml
	function getContentHtml() {
		let html = _d.config.content;
		// 分割
		let aHtml = html.split('##');
		html = '';
		aHtml.forEach((str, index) => {
			if(str.indexOf('json:') == 0) {
				let obj = JSON.parse(str.substring(5));
				let oTool = _d.gdTools.find(item => item.id == obj.id);
				let value = oTool.value;
				if(obj.type == 'textarea') {
					value = formatText(value);
				} else if (obj.type == 'choiceUnit') {
					value = value ? JSON.parse(value).name : '';
				}
				if(obj.format) {
					value = formatValue(value, obj.format);
				}
				html+=value;
			} else {
				html+=str;
			}
		})
		return html;
	}

	// 导出
	function exportPdf() {
		exportBoxRef.value.innerHTML = getContentHtml();
		setTimeout(() => {
			// 导出pdf
			downloadPDF(exportBoxRef.value, '表单');
		}, 100);
	}

	// 打印
	function printPdf() {
		let html = getContentHtml();
		exportBoxRef.value.innerHTML = html;
		setTimeout(() => {
			html2canvas(exportBoxRef.value).then(async (canvas) => {
				const image = canvas.toDataURL('image/jpeg', 1.0);
				const newWin = window.open('');
				newWin.document.body.innerHTML = `<img style="max-width:100%;display:block;" src="${image}" />`
				newWin.document.close()
		    newWin.focus()
		    setTimeout(() => {
		      newWin.print()
		      newWin.close()
		    }, 300)
			})
		}, 100);
	}

	// 格式化文本
	function formatText(text) {
		text = text.replace(/ /g, '&nbsp;');
		let arr = text.split('\n');
		text = arr.join('<br/>');
		return text;
	}

	// 格式化值
	function formatValue(value, format) {
		let code = `window.formatFunction = function (value) { ${format} }`;
		eval(code);
		return window.formatFunction(value);
	}

	// 保存
	function savePdf() {
		// if(_d.config.save) {
		// 	let code = `window.saveFunction = function(request, ElMessage, tableTools) {${_d.config.save}}`;
		// 	eval(code);
		// 	window.saveFunction(request, ElMessage, _d.table);
		// }
		console.log(JSON.stringify(_d.config));

	}

	// 拷贝代码
	function copyCode() {
		_d.config.content = getContentCode();
		copyToClipboard(JSON.stringify(_d.config));
	}

	// 获取代码
	function getCode() {
		if(_d.config.save) {
			let code = `window.saveFunction = function(route, request, ElMessage, Tools, oBox) {${_d.config.save}}`;
			eval(code);
			window.saveFunction(route, request, ElMessage, _d.gdTools, pdfBoxRef.value);
		}
		_d.config.content = getContentCode();
		return JSON.stringify(_d.config);
	}

	window.openTemplateModal = function (type) {
		if(!type) {
			console.log('type不能为空')
			return;
		}
		if(type == 'addSupplierManageRef') {
			addSupplierManageRef.value.open();
		} else if (type == 'addSupplierManagePersonRef') {
			addSupplierManagePersonRef.value.open();
		}
	}

	defineExpose({
		export: exportPdf,
		print: printPdf,
		save: savePdf,
		copy: copyCode,
		getCode: getCode
	})

</script>

<style lang="scss">
.excel-preivew-wp {
	position: relative;
	width: 100%;
	padding: 10px 10px 0;
	text-align: center;
	table {
		border-collapse: collapse;
	}
	.pdf-box {
		position: relative;
		display: inline-block;
		.handle-box {
			padding-top: 10px;
			text-align: center;
		}
	}

	.sub-box {
		padding: 20px 10px 0;
		text-align: center;
	}
		
	.gd-table {
		position: absolute;
		z-index: -101;
		bottom: 0;
		left: 0;
		opacity: 0;
	}

	.gd-tools {
		position: absolute;
		z-index: -100;
		bottom: 0;
		left: 0;
		opacity: 0;
	}
}

.export-box {
	position: fixed;
	z-index: -100;
	top: 0;
	left: 0;
	padding: 25px 0;
	background: #fff;
	table {
		margin: 0 auto;
	}
}

.tbody-handle {
	position: fixed;
	z-index: 100;
	bottom: 100px;
	right: 50px;
	&:hover {
		.handle-box {
			display: block;
		}
	}
	.show-text {
		padding-top: 9px;
		width: 50px;
		height: 50px;
		border-radius:50%;
		box-shadow: 0 2px 12px rgba(0,0,0,0.2);
		text-align:center;
		font-size: 14px;
		line-height: 16px;
		background: #fff;
	}
	.handle-box {
		display: none;
		position: absolute;
		bottom: 48px;
		right: 0;
		background: #fff;
		box-shadow: 0 2px 12px rgba(0,0,0,0.1);
		border-radius: 4px;
		padding: 10px 15px 10px 10px;
		.row {
			display: flex;
			align-items: center;
			white-space: nowrap;
			.copy, .add {
				margin-right: 5px;
				margin-left: 0;
			}
			.ipt {
				width: 60px;
			}
			&+.row {
				margin-top: 10px;
			}
		}
	}
}

</style>